package org.gdstash.db;

import org.gdstash.file.ARCDecompress;
import org.gdstash.file.ARZRecord;
import org.gdstash.ui.GDStashFrame;
import org.gdstash.util.GDConstants;
import org.gdstash.util.GDMsgFormatter;
import org.gdstash.util.GDMsgLogger;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class DBFactionReputation {
    private static final String TABLE_NAME = "GDC_FACTION_REPUTATION";
    private static final int ROW_INDEX = 1;
    private static final int ROW_VALUE = 2;
    private static final int ROW_STATE_TAG = 3;
    private static final int ROW_STATE = 4;
    private int index;
    private int value;
    private String stateTag;
    private String stateText;

    private static List<DBFactionReputation> wrap(final ResultSet rs) throws SQLException {
        final List<DBFactionReputation> list = new ArrayList<DBFactionReputation>(8);
        while (rs.next()) {
            final DBFactionReputation rep = new DBFactionReputation();
            rep.index = rs.getInt(1);
            rep.value = rs.getInt(2);
            rep.stateTag = rs.getString(3);
            rep.stateText = rs.getString(4);
            if (rep.stateText != null) {
                final ByteBuffer buffer = StandardCharsets.UTF_8.encode(rep.stateText);
                final String utf8 = StandardCharsets.UTF_8.decode(buffer).toString();
                rep.stateText = utf8;
            }
            if (rep.index > 0) {
                list.add(rep);
            }
        }
        return list;
    }

    public int getIndex() {
        return this.index;
    }

    public void setIndex(final int index) {
        this.index = index;
    }

    public int getValue() {
        return this.value;
    }

    public void setValue(final int value) {
        this.value = value;
    }

    public String getStateTag() {
        return this.stateTag;
    }

    public void setStateTag(final String stateTag) {
        this.stateTag = stateTag;
        if (stateTag == null) {
            this.stateText = null;
        } else {
            this.stateText = GDStashFrame.arcList.getTag(ARCDecompress.FileModule.All, GDConstants.TAG_TEXT_UI, stateTag, false);
        }
    }

    public static void createTable(final Connection conn) throws SQLException {
        final String dropTable = "DROP TABLE GDC_FACTION_REPUTATION";
        final String createTable = "CREATE TABLE GDC_FACTION_REPUTATION (INDEX       INTEGER NOT NULL, VALUE       INTEGER, STATE_TAG   VARCHAR(64), STATE_TEXT  VARCHAR(256), PRIMARY KEY (INDEX))";
        try (final Statement st = conn.createStatement()) {
            if (GDDBUtil.tableExists(conn, "GDC_FACTION_REPUTATION")) {
                st.execute(dropTable);
            }
            st.execute(createTable);
            st.close();
            conn.commit();
        } catch (SQLException ex) {
            conn.rollback();
            final Object[] args = {"GDC_FACTION_REPUTATION"};
            final String msg = GDMsgFormatter.format(GDMsgFormatter.rbMsg, "ERR_CREATE_TABLE", args);
            GDMsgLogger.addError(msg);
            throw ex;
        }
    }

    public static void delete(final Connection conn) throws SQLException {
        final String deleteEntry = "DELETE FROM GDC_FACTION_REPUTATION";
        try (final PreparedStatement ps = conn.prepareStatement(deleteEntry)) {
            ps.executeUpdate();
            ps.close();
        } catch (SQLException ex) {
            throw ex;
        }
    }

    public static void insert(final Connection conn, final ARZRecord record, final DBFactionReputation reputation) throws SQLException {
        final String insert = "INSERT INTO GDC_FACTION_REPUTATION VALUES (?,?,?,?)";
        try (final PreparedStatement ps = conn.prepareStatement(insert)) {
            if (reputation.index > 0) {
                ps.setInt(1, reputation.index);
                ps.setInt(2, reputation.value);
                ps.setString(3, reputation.stateTag);
                ps.setString(4, reputation.stateText);
                ps.executeUpdate();
                ps.clearParameters();
                ps.close();
                conn.commit();
            }
        }
    }

    public static List<DBFactionReputation> get() {
        List<DBFactionReputation> list = null;
        final String command = "SELECT * FROM GDC_FACTION_REPUTATION ORDER BY VALUE";
        try (final Connection conn = GDDBData.getConnection();
             final PreparedStatement ps = conn.prepareStatement(command)) {
            try (final ResultSet rs = ps.executeQuery()) {
                list = wrap(rs);
                conn.commit();
            } catch (SQLException ex) {
                throw ex;
            }
        } catch (SQLException ex2) {
            final Object[] args = {"-", "GDC_FACTION_REPUTATION"};
            final String msg = GDMsgFormatter.format(GDMsgFormatter.rbMsg, "ERR_READ_TABLE_BY_ID", args);
            GDMsgLogger.addError(msg);
            GDMsgLogger.addError(ex2);
        }
        return list;
    }

    public String getStateText() {
        return this.stateText;
    }
}
